package org.zxyj.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 常用日期工具类
 * 
 * @author zhaoyong
 */
public class DateUtil {

	private static SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

	/**
	 * 格式：yyyy-MM-dd HH:mm:ss（eg:2014-01-01 12:12:12）
	 */
	public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 格式：yyyy-MM-dd（eg:2014-01-01）
	 */
	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

	/**
	 * 格式：yyyyMM（eg:201401）
	 */
	public static final String YYYYMM_DATE_FORMAT = "yyyyMM";

	/**
	 * 格式：yyyyMMddHHmmss（eg:20140101121212）
	 */
	public static final String YMDHMS_DATE_FORMAT = "yyyyMMddHHmmss";

	/**
	 * 私有构造函数
	 */
	private DateUtil() {
	}

	/**
	 * 获取当前时间的“年”
	 * 
	 * @return “年” (整数型)
	 */
	public static int getYear() {
		int year = Calendar.getInstance().get(Calendar.YEAR);
		return year;
	}

	/**
	 * 获取当前时间的“月”
	 * 
	 * @return “月” (整数型)
	 */
	public static int getMonth() {
		int motn = Calendar.getInstance().get(Calendar.MONTH);
		return motn;
	}

	/**
	 * 获取当前时间的“日”
	 * 
	 * @return “日” (整数型)
	 */
	public static int getDay() {
		int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
		return day;
	}

	/**
	 * 获取当前时间的“星期”
	 * 
	 * @return “星期” (整数型)
	 */
	public static int getWeekday() {
		int week = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
		return week;
	}

	/**
	 * 获取当前时间的“时”
	 * 
	 * @return “小时” (整数型)
	 */
	public static int getHour() {
		int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		return hour;
	}

	/**
	 * 获取当前时间的“分”
	 * 
	 * @return “分” (整数型)
	 */
	public static int getMinute() {
		int minute = Calendar.getInstance().get(Calendar.MINUTE);
		return minute;
	}

	/**
	 * 获取当前时间的“秒”
	 * 
	 * @return “秒” (整数型)
	 */
	public static int getSecond() {
		int second = Calendar.getInstance().get(Calendar.SECOND);
		return second;
	}

	/**
	 * 获取当前时间的“毫秒”
	 * 
	 * @return “毫秒” (整数型)
	 */
	public static int getMilliSecond() {
		int milliSecond = Calendar.getInstance().get(Calendar.MILLISECOND);
		return milliSecond;
	}

	/**
	 * <b>日期比较</b><br>
	 * <p>
	 * 判断日期date1是否在日期date2之后
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return true:date1在date2之后 , false:date1不在date2之后（<=）
	 * @throws ParseException
	 */
	public static boolean after(String date1, String date2) throws ParseException {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		return calendar1.compareTo(calendar2) == 1 ? true : false;
	}

	/**
	 * <b>日期比较</b><br>
	 * <p>
	 * 判断日期date1是否在日期date2之前
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return true:date1在date2之前 , false:date1不在date2之前（>=）
	 * @throws ParseException
	 */
	public static boolean before(String date1, String date2) throws ParseException {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		return calendar1.compareTo(calendar2) == -1 ? true : false;
	}

	/**
	 * <b>日期比较</b><br>
	 * <p>
	 * 判断日期date1是否与日期date2相等
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return true:date1与date2相等 , false:date1等于date2（> or <）
	 * @throws ParseException
	 */
	public static boolean equals(String date1, String date2) throws ParseException {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		return calendar1.compareTo(calendar2) == 0 ? true : false;
	}

	/**
	 * <b>日期计算</b><br>
	 * <p>
	 * 两个日期相差的年数
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return 年数（整数型）
	 * @throws ParseException
	 */
	public static int diffYear(String date1, String date2) throws ParseException {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		return calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR);
	}

	/**
	 * <b>日期计算</b><br>
	 * <p>
	 * 两个日期相差的月数
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return 月数（整数型）
	 * @throws ParseException
	 */
	public static int diffMonth(String date1, String date2) throws ParseException {
		int months = 0;
		if (after(date1, date2)) {
			String temp;
			temp = date1;
			date1 = date2;
			date2 = temp;
		} else if (equals(date1, date2)) {
			return 0;
		}
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		int year1 = calendar1.get(Calendar.YEAR);
		int year2 = calendar2.get(Calendar.YEAR);
		int moth1 = calendar1.get(Calendar.MONTH);
		int moth2 = calendar2.get(Calendar.MONTH);
		if (before(add(date1, year2 - year1, Calendar.YEAR), date2)) {
			if (before(add(add(date1, year2 - year1, Calendar.YEAR), moth2 - moth1, Calendar.MONTH), date2)) {
				months = (year2 - year1) * 12 + (moth2 - moth1);
			} else if (equals(add(add(date1, year2 - year1, Calendar.YEAR), moth2 - moth1, Calendar.MONTH), date2)) {
				months = (year2 - year1) * 12 + (moth2 - moth1);
			} else {
				months = (year2 - year1) * 12 + (moth2 - moth1) - 1;
			}
		} else if (equals(add(date1, year2 - year1, Calendar.YEAR), date2)) {
			months = (year2 - year1) * 12;
		} else {
			if (before(add(add(date1, year2 - year1, Calendar.YEAR), moth2 - moth1, Calendar.MONTH), date2)) {
				months = (year2 - year1) * 12 - (moth1 - moth2);
			} else if (equals(add(add(date1, year2 - year1, Calendar.YEAR), moth2 - moth1, Calendar.MONTH), date2)) {
				months = (year2 - year1) * 12 - (moth1 - moth2);
			} else {
				months = (year2 - year1) * 12 - (moth1 - moth2) - 1;
			}
		}
		return months;
	}

	/**
	 * <b>日期计算</b><br>
	 * <p>
	 * 两个日期相差的天数
	 * </p>
	 * 
	 * @param date1
	 *            字符串格式日期值
	 * @param date2
	 *            字符串格式日期值
	 * @return 天数（整数型）
	 * @throws ParseException
	 */
	public static long diffDay(String date1, String date2) throws ParseException {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(datetimeFormat.parse(date1));
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(datetimeFormat.parse(date2));
		return (calendar1.getTimeInMillis() - calendar2.getTimeInMillis()) / (24 * 60 * 60 * 1000);
	}

	/**
	 * <b>日期转换</b><br>
	 * <p>
	 * 将传入的字符串格式日期值转换成Calendar对象
	 * </p>
	 * 
	 * @param date
	 *            字符串格式日期值
	 * @return Calendar对象的日期
	 * @throws ParseException
	 */
	public static Calendar getDateFromStr(String date) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(datetimeFormat.parse(date));
		return calendar;
	}

	public static Date getDate(String date) throws ParseException {
		return datetimeFormat.parse(date);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 获取指定年和月的第一天
	 * </p>
	 * 
	 * @param year
	 *            年
	 * @param moth
	 *            月
	 * @return 日期格式字串（yyyy-MM-dd）
	 * @throws ParseException
	 */
	public static String getFirstDayFromYM(String year, String moth) {
		if (Integer.parseInt(moth) > 0 && Integer.parseInt(moth) < 10) {
			return year + "-0" + Integer.parseInt(moth) + "-" + "01 00:00:00";
		} else {
			if (Integer.parseInt(moth) <= 0) {
				return year + "-01-" + "01";
			}
			return year + "-" + moth + "-" + "01";
		}

	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 获取指定年和月的最后一天（即：月末）
	 * </p>
	 * 
	 * @param year
	 *            年
	 * @param moth
	 *            月
	 * @return 日期格式字串（yyyy-MM-dd）
	 * @throws ParseException
	 */
	public static String getLastDayFromYM(String year, String moth) throws ParseException {
		return add(add(getFirstDayFromYM(year, moth), 1, Calendar.MONTH), -1, Calendar.DAY_OF_MONTH);
	}

	/**
	 * 
	 * @param date
	 * @param amount
	 * @param field
	 * @return String型
	 * @throws ParseException
	 */
	private static String add(String date, int amount, int field) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dateFormat.parse(date));
		calendar.add(field, amount);
		return datetimeFormat.format(calendar.getTime());
	}

	/**
	 * 
	 * @param date
	 * @param amount
	 * @param field
	 * @return Date型
	 */
	private static Date add(Date date, int amount, int field) {
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(date);
		calendar.add(field, amount);

		return calendar.getTime();
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 获取当前系统日期的第最后一天（即：月末）
	 * </p>
	 * 
	 * @return Date型
	 * @throws ParseException
	 */
	public static Date getMonthLastDay() {
		return getMonthLastDay(getNow());
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 获取指定日期的第最后一天（即：月末）
	 * 
	 * @param date
	 *            Date型
	 * @return Date型
	 * @throws ParseException
	 */
	public static Date getMonthLastDay(Date date) {

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, 1);
		calendar.add(Calendar.DATE, -1);

		return calendar.getTime();
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 字符串格式的日期转换为日期型
	 * </p>
	 * 
	 * @param datestr
	 *            字符串格式的日期
	 * @param pattern
	 *            格式
	 * @return Date型
	 */
	public static Date parse(String datestr, String pattern) {
		Date date = null;

		if (null == pattern || "".equals(pattern)) {
			pattern = DEFAULT_DATE_FORMAT;
		}

		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
			date = dateFormat.parse(datestr);
		} catch (ParseException e) {

		}

		return date;
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统当前日期时间
	 * </p>
	 * 
	 * @return Date型
	 */
	public static Date getNow() {
		return Calendar.getInstance().getTime();
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统当前日期 （yyyy-MM-dd）
	 * </p>
	 * 
	 * @return String型
	 */
	public static String getDate() {
		return getDateTime(DEFAULT_DATE_FORMAT);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统当前日期推前3个月的日期 （yyyy-MM-dd）
	 * 
	 * @return String型
	 */
	public static String getDateOld3MM() {
		Date newDate = Calendar.getInstance().getTime();
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(newDate);
		gc.add(2, -3);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(gc.getTime());
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统当前日期的年月 （yyyyMM）
	 * </p>
	 * 
	 * @return String型
	 */
	public static String getDate_yyyyMM() {
		return getDateTime(YYYYMM_DATE_FORMAT);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统日期时间 （yyyy-MM-dd HH:mm:ss）
	 * 
	 * @return String型
	 */
	public static String getDateTime() {
		return getDateTime(DEFAULT_DATETIME_FORMAT);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得系统日期时间 （yyyyMMddHHmmss）
	 * </p>
	 * 
	 * @return String型
	 */
	public static String getDateTime_YMDHMS() {
		return getDateTime(YMDHMS_DATE_FORMAT);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 取得指定格式的当前系统时间
	 * </p>
	 * 
	 * @param pattern
	 *            日期格式
	 * @return String型
	 */
	public static String getDateTime(String pattern) {
		Date datetime = Calendar.getInstance().getTime();

		return getDateTime(datetime, pattern);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 指定日期,指定格式的日期串
	 * </p>
	 * 
	 * @param date
	 *            指定日期值（Date型）
	 * @param pattern
	 *            日期格式 。pattern=null时，默认为：yyyy-MM-dd HH:mm:ss
	 * @return String型
	 */
	public static String getDateTime(Date date, String pattern) {
		if (null == pattern || "".equals(pattern)) {
			pattern = DEFAULT_DATETIME_FORMAT;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(date);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 指定日期,n天以后或之前的时间
	 * </p>
	 * 
	 * @param date
	 *            指定日期值（Date型）
	 * @param days
	 *            天数（整数）。可以为负数的时候为指定的日期之前天数的时间。
	 * @return Date型
	 */
	public static Date addDays(Date date, int days) {
		return add(date, days, Calendar.DATE);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 当前系统日期的n天以后或以前
	 * </p>
	 * 
	 * @param days
	 *            天数（整数）。可以为负数的时候为系统日期之前天数的时间。
	 * @return Date型
	 */
	public static Date addDays(int days) {
		return add(getNow(), days, Calendar.DATE);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 当前日期的n月以后
	 * </p>
	 * 
	 * @param months
	 *            月数（整数）。可以为负数的时候为系统日期之前月数的时间。
	 * @return Date型
	 */
	public static Date addMonths(int months) {
		return add(getNow(), months, Calendar.MONTH);
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 指定日期的n月以后或之前的时间
	 * </p>
	 * 
	 * @param date
	 *            指定日期（日期型）
	 * @param months
	 *            月数（整数）。可以为负数的时候为指定日期之前月数的时间。
	 * @return Date型
	 */
	public static Date addMonths(Date date, int months) {
		return add(date, months, Calendar.MONTH);
	}

	/**
	 * <b>日期字符串取得<b><br>
	 * <p>
	 * 获取当前系统时间“年月日时分秒毫秒”字符串
	 * </p>
	 * 
	 * @return String型
	 */
	public static String getDateYMDHMSSSSS() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return sdf.format(new Date());
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 获取当前系统时间的年月日
	 * </p>
	 * 
	 * @return Date型
	 */
	public static Date getDateYMD() throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.parse(sdf.format(new Date()));
	}

	/**
	 * <b>日期取得</b><br>
	 * <p>
	 * 指定日期与格式得到字符串格式的时间
	 * </p>
	 * 
	 * @param date
	 *            指定日期（Date型）
	 * @param format
	 *            指定格式
	 * @return String型
	 */
	public static String getDateForPara(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}
}
